{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "3.3.ipynb",
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/yananma/5_programs_per_day/blob/master/pytorch/ch3/3_3.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "n70Qs59tI4tD",
        "colab_type": "text"
      },
      "source": [
        "## 3.3 线性回归的简洁实现"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "63JKfBVNKYwN",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.1 生成数据集"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZsnSzXnOKchU",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch \n",
        "from torch import nn \n",
        "import numpy as np "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BqfNWJJoNwec",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "num_inputs = 2 \n",
        "num_examples = 1000 \n",
        "true_w = [2, -3.4]\n",
        "true_b = 4.2 \n",
        "features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float)\n",
        "labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b \n",
        "labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Gec6trHcOe28",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.2 读取数据集"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "d1uf8UaxOlSG",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import torch.utils.data as Data \n",
        "\n",
        "batch_size = 10 \n",
        "dataset = Data.TensorDataset(features, labels)\n",
        "data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kYwSp0OLPLtx",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# Data.DataLoader??\n",
        "# Data loader. Combines a dataset and a sampler, and provides an iterable over the given dataset."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5Hzun8BTP1qI",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 218
        },
        "outputId": "21ae6bcb-6573-492e-ea89-dc599367ebff"
      },
      "source": [
        "for X, y in data_iter:\n",
        "    print(X, '\\n', y)\n",
        "    break "
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "tensor([[ 1.4424, -0.4708],\n",
            "        [ 0.8540, -0.9407],\n",
            "        [ 1.6333, -0.6412],\n",
            "        [ 0.9610,  0.7797],\n",
            "        [-0.0249,  1.3809],\n",
            "        [ 0.4529, -1.2042],\n",
            "        [-1.3523, -2.3790],\n",
            "        [ 2.1326,  0.7625],\n",
            "        [ 0.4740, -1.8160],\n",
            "        [ 2.6771, -0.1584]]) \n",
            " tensor([ 8.6925,  9.1228,  9.6347,  3.4623, -0.5443,  9.1931,  9.5950,  5.8613,\n",
            "        11.3102, 10.0727])\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Xz5AhiW1P99x",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.3 定义模型"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bCW9XOt_Qgz6",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 67
        },
        "outputId": "5c0c5241-d1ee-4ab7-be27-534f05cf2ae7"
      },
      "source": [
        "# 内部实现，和这一节无关\n",
        "class LinearNet(nn.Module):\n",
        "    def __init__(self, n_feature):\n",
        "        super(LinearNet, self).__init__()\n",
        "        self.linear = nn.Linear(n_feature, 1)  # 阿拉伯数字 1，输出 1 个\n",
        "\n",
        "    def forward(self, x):\n",
        "        y = self.linear(x)\n",
        "        return y \n",
        "\n",
        "net = LinearNet(num_inputs)\n",
        "print(net)"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "LinearNet(\n",
            "  (linear): Linear(in_features=2, out_features=1, bias=True)\n",
            ")\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "PvZYuphxReeh",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 84
        },
        "outputId": "c734a859-e1ef-46bb-91ab-a350cbdc6131"
      },
      "source": [
        "net = nn.Sequential(\n",
        "    nn.Linear(num_inputs, 1)\n",
        ")\n",
        "\n",
        "print(net)\n",
        "print(net[0])"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Sequential(\n",
            "  (0): Linear(in_features=2, out_features=1, bias=True)\n",
            ")\n",
            "Linear(in_features=2, out_features=1, bias=True)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M0UWSCQoR7oN",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 84
        },
        "outputId": "70279f8a-2200-4595-88ac-6024f17cdee1"
      },
      "source": [
        "# 查看模型所有的可学习参数，也就是 weight 和 bias\n",
        "for param in net.parameters():\n",
        "    print(param)"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Parameter containing:\n",
            "tensor([[-0.4866,  0.1314]], requires_grad=True)\n",
            "Parameter containing:\n",
            "tensor([-0.2363], requires_grad=True)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "P8wW3e_-SNrq",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.4 初始化模型参数"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7vtuk3VvSEH3",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 50
        },
        "outputId": "11f3ff90-4f39-4d11-a561-6f3a7605fe34"
      },
      "source": [
        "from torch.nn import init \n",
        "\n",
        "init.normal_(net[0].weight, mean=0.0, std=0.01)\n",
        "init.constant_(net[0].bias, val=0.0)"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "Parameter containing:\n",
              "tensor([0.], requires_grad=True)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Kyq3HChtXEEE",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.5 定义损失函数"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Xg_OZxrgXY3w",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "loss = nn.MSELoss()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "I7KurpTOXcTQ",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "8a950f69-54e2-4edd-ceae-39a0ce3b82c8"
      },
      "source": [
        "# my_y_hat = torch.tensor([0., 0., 0.])\n",
        "# my_y = torch.tensor([3., 3., 3.])\n",
        "# loss(my_y_hat, my_y)  \n",
        "\n",
        "# 对应相减\n",
        "# 每一项平方\n",
        "# 所有项求和\n",
        "# 最后求平均"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "tensor(9.)"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 17
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UwONrbMkaj5U",
        "colab_type": "text"
      },
      "source": [
        "### 3.3.6 定义优化算法"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t7Ze898Negst",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 151
        },
        "outputId": "ead8098a-bd62-47f4-9cf7-ad94f6df4d35"
      },
      "source": [
        "from torch import optim \n",
        "\n",
        "optimizer = optim.SGD(net.parameters(), lr=0.03)\n",
        "optimizer"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "SGD (\n",
              "Parameter Group 0\n",
              "    dampening: 0\n",
              "    lr: 0.03\n",
              "    momentum: 0\n",
              "    nesterov: False\n",
              "    weight_decay: 0\n",
              ")"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 18
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qZT9ivLqe1V2",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 67
        },
        "outputId": "caa6a4c8-18c5-4f5c-e53d-40e38f0d3c8f"
      },
      "source": [
        "num_epochs = 3 \n",
        "for epoch in range(1, num_epochs + 1):\n",
        "    for X, y in data_iter:\n",
        "        output = net(X)\n",
        "        l = loss(output, y.view(-1, 1))\n",
        "        optimizer.zero_grad()\n",
        "        l.backward()\n",
        "        optimizer.step()\n",
        "    print('epoch %d, loss: %f' %(epoch, l.item()))"
      ],
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "epoch 1, loss: 0.000753\n",
            "epoch 2, loss: 0.000074\n",
            "epoch 3, loss: 0.000043\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2w0BddriiPMW",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# optimizer.zero_grad??\n",
        "\n",
        "# Clears the gradients of all optimized :class:`torch.Tensor "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "E9o0AkLii7G6",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# l.backward??\n",
        "\n",
        "# Computes the gradient of current tensor w.r.t. graph leaves.\n",
        "\n",
        "# 使用前，要清零\n",
        "# This function accumulates gradients in the leaves - you might need to zero them before calling it."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "J5fnTC9wihMZ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# optimizer.step??\n",
        "\n",
        "# Performs a single optimization step."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "KIv2ikkigiP7",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "8c362825-4334-47fd-a482-c8b962701d40"
      },
      "source": [
        "true_w, net[0].weight.data"
      ],
      "execution_count": 23,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "([2, -3.4], tensor([[ 1.9994, -3.4002]]))"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 23
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "o4XX3Zwsgxfw",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "e0e36ebc-e053-4d0b-b348-08c811b0032c"
      },
      "source": [
        "true_b, net[0].bias.data"
      ],
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(4.2, tensor([4.2003]))"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 24
        }
      ]
    }
  ]
}